package com.wl.api.service.system.impl;

import static com.wl.api.common.utils.PageInfo.transfromPage;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.wl.api.common.utils.BeanUtils;
import com.wl.api.common.utils.CollectionUtil;
import com.wl.api.common.utils.ObjectUtil;
import com.wl.api.common.utils.PageInfo;
import com.wl.api.common.utils.StringUtil;
import com.wl.api.common.utils.constant.ClientConstant;
import com.wl.api.dto.system.SecurityAreaLadderExtendDTO;
import com.wl.api.dto.system.SecurityChannelDTO;
import com.wl.api.dto.system.SecurityChannelLadderPriceDTO;
import com.wl.api.mapper.system.SecurityChannelMapper;
import com.wl.api.model.system.SecurityChannel;
import com.wl.api.model.system.SecurityChannelFrom;
import com.wl.api.model.system.SecurityChannelLadderPrice;
import com.wl.api.model.system.SecurityChannelReach;
import com.wl.api.service.system.ISecurityChannelAreaLadderPriceService;
import com.wl.api.service.system.ISecurityChannelFromService;
import com.wl.api.service.system.ISecurityChannelLadderPriceService;
import com.wl.api.service.system.ISecurityChannelReachService;
import com.wl.api.service.system.ISecurityChannelService;

/**
 *
 * SecurityChannel 表数据服务层接口实现类
 *
 */
@Service
public class SecurityChannelServiceImpl extends ServiceImpl<SecurityChannelMapper, SecurityChannel> implements ISecurityChannelService {

	@Autowired
	ISecurityChannelLadderPriceService channelLadderPriceService;
	@Autowired
	ISecurityChannelReachService channelReachService;
	@Autowired
	ISecurityChannelFromService channelFromService;
	@Autowired
	ISecurityChannelAreaLadderPriceService areaLadderPriceService;
	@Autowired
	SecurityChannelMapper channelMapper;
	//这里渠道和ladder price baing
	@Transactional
	public Long insertChannelLogistics(SecurityChannelDTO param) {
		SecurityChannel entity = BeanUtils.copyProperties(param, SecurityChannel.class);
		insert(entity);
		channelFromService.insert(SecurityChannelFrom.builder().areaId(param.getFromAreaId()).channelId(entity.getId()).build()); 
		channelReachService.insert(SecurityChannelReach.builder().areaId(param.getReachAreaId()).channelId(entity.getId()).build());
		List<SecurityChannelLadderPrice> ladderPrices = param.getFeeLadderList().parallelStream()
				                   .map(s -> SecurityChannelLadderPrice.builder().amount(s.getAmount()).channelId(entity.getId())
				                		   .createTime(new Date()).feeType(ClientConstant.fee_type_logistics).weightFrom(s.getWeightFrom()).weightTo(s.getWeightTo()).build()).collect(Collectors.toList());
		channelLadderPriceService.insertBatch(ladderPrices);
		
		return entity.getId();
		
	}
	
	public Long updateChannelLogistics(SecurityChannelDTO param) {
		updateById(BeanUtils.copyProperties(param, SecurityChannel.class));
		channelFromService.update(SecurityChannelFrom.builder().areaId(param.getFromAreaId()).build(), new EntityWrapper<SecurityChannelFrom>().where("channel_id", param.getId()));
		channelReachService.update(SecurityChannelReach.builder().areaId(param.getFromAreaId()).build(), new EntityWrapper<SecurityChannelReach>().where("channel_id", param.getId()));

		List<SecurityChannelLadderPrice> source =  channelLadderPriceService.selectList(new EntityWrapper<SecurityChannelLadderPrice>().where("channel_id", param.getId()));
		List<Long> delIds = new ArrayList<Long>();
		List<SecurityChannelLadderPrice> updateList = param.getFeeLadderList().parallelStream().filter(s -> !ObjectUtil.isEmpty(s.getId())).map(s -> BeanUtils.copyProperties(s, SecurityChannelLadderPrice.class)).collect(Collectors.toList()); 
		List<SecurityChannelLadderPrice> insertList = param.getFeeLadderList().parallelStream().filter(s -> ObjectUtil.isEmpty(s.getId())).map(s -> BeanUtils.copyProperties(s, SecurityChannelLadderPrice.class)).collect(Collectors.toList());
		//del 
		if (!CollectionUtil.isEmpty(source)) {
			for(SecurityChannelLadderPrice sc: source) {
				if (CollectionUtil.isEmpty(updateList)) {
					delIds.add(sc.getId());
					continue;
				}
				if (updateList.parallelStream().noneMatch(s -> Objects.equals(s.getId(), sc.getId()))) {
					delIds.add(sc.getId());
					continue;
				}
			}
		}
		
		if(!CollectionUtil.isEmpty(delIds)) {
			channelLadderPriceService.deleteBatchIds(delIds);
		}
		if (!CollectionUtil.isEmpty(updateList)) {
			channelLadderPriceService.updateBatchById(updateList);
		}
		if (!CollectionUtil.isEmpty(insertList)) {
			channelLadderPriceService.insertBatch(insertList);
		}
		
		return param.getId();
	}
	
	
	public PageInfo<SecurityChannelDTO> getItemList(SecurityChannelDTO param) {
		Wrapper<SecurityChannel> wrapper = new EntityWrapper<>();
		
		if (!StringUtil.isEmpty(param.getName())) {
			wrapper.like("name", param.getName());
		}
		if (param.getStatus() != null) {
			wrapper.andNew("status",  param.getStatus());
		}
		Page<SecurityChannel> page = selectPage(new Page<>(param.getPage(), param.getPageSize(), "update_time desc"), wrapper);
		return transfromPage(SecurityChannelDTO.class, page);
	}
	

	public SecurityChannelDTO getDetail(SecurityChannelDTO param) {
		SecurityChannelDTO data = new SecurityChannelDTO();
		SecurityChannel channel = selectById(param.getId()); 
		if (Objects.isNull(channel)) {
			return data;
		}
		data = BeanUtils.copyProperties(channel, SecurityChannelDTO.class);
		SecurityChannelFrom from = channelFromService.selectOne(new EntityWrapper<SecurityChannelFrom>().where("channel_id", param.getId()));
		if (Objects.nonNull(from)) {
			data.buildPickUpLadders(from.getAreaId(), areaLadderPriceService.getAreaLadderDetail(SecurityAreaLadderExtendDTO.builder().countryId(from.getAreaId()).feeType(ClientConstant.FEE_TYPE_PICK_UP).build()).getPickUpLadderlList());
		}
		SecurityChannelReach reach = channelReachService.selectOne(new EntityWrapper<SecurityChannelReach>().where("channel_id", param.getId())); 
		if (Objects.nonNull(reach)) {
			data.buildDeliveryLadders(reach.getAreaId(), areaLadderPriceService.getAreaLadderDetail(SecurityAreaLadderExtendDTO.builder().countryId(reach.getAreaId()).feeType(ClientConstant.fee_type_delivery).build()).getDeliveryLadderList());
		}
		
		return data.buildLogisticsLadders(BeanUtils.copyProperties(channelLadderPriceService.selectList(new EntityWrapper<SecurityChannelLadderPrice>().where("channel_id", param.getId())), SecurityChannelLadderPriceDTO.class));
	}

	@Override
	public List<SecurityChannelDTO> queryChannelPrice(Long fromId,
			Long reachId, String weight) {
		 List<Long>  channelList = channelMapper.getChannelsByFromAndReach(fromId, reachId);
		 if (CollectionUtil.isEmpty(channelList)) {
			return new ArrayList<SecurityChannelDTO>();
		}
		List<SecurityChannel> list = selectList(new EntityWrapper<SecurityChannel>().in("id", channelList)); 
		List<SecurityChannelLadderPrice> prices= channelLadderPriceService.selectList(new EntityWrapper<SecurityChannelLadderPrice>().in("channel_id", channelList));
		return null;
	}
	

}